//
//  MenuView.m
//  PopMenuTableView
//
//  Created by LoadingMx on 2017/9/18.
//  Copyright © 2017年 LoadingMx. All rights reserved.
//

#import "MenuView.h"
#import "UIView+Extensions.h"

#define kTriangleHeight 10
#define kMarkViewTag 666
#define kMenuTag 888
#define kMargin 8
#define kRadius 5
#define kDefaultMaxValue 6
#define kMenuItemsHeight 40

@interface MenuView () <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) MenuView *selfMenu;
@property (nonatomic, strong) UITableView *contentTableView;
@property (nonatomic, strong) NSMutableArray *menuDataArray;

@end
@implementation MenuView {
    UIView *_backView;
    CGFloat arrowPointX; // 箭头位置
}

- (void)setMenuDataArray:(NSMutableArray *)menuDataArray {
    if (!_menuDataArray) {
        _menuDataArray = [NSMutableArray array];
        
    }
    [menuDataArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (![obj isKindOfClass:[MenuModel class]]) {
            MenuModel *model = [MenuModel MenuModelWithDict:(NSDictionary*)obj];
            [_menuDataArray addObject:model];
        }
    }];
}

- (void)setMaxValueForItemCount:(NSInteger)maxValueForItemCount {
    if (maxValueForItemCount <= kDefaultMaxValue) {
        _maxValueForItemCount = maxValueForItemCount;
    } else {
        _maxValueForItemCount = kDefaultMaxValue;
    }
}


- (instancetype)initWithFrame:(CGRect)frame {
    if (self == [super initWithFrame:frame]) {
        [self setupUI];
    }
    return self;
}

- (void)setupUI {
    self.backgroundColor = [UIColor colorWithRed:61/255.0 green:61/255.0 blue:61/255.0 alpha:1];
    
    arrowPointX = self.width * 0.5;
    UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, kTriangleHeight, self.width, self.height)];
    tableView.delegate = self;
    tableView.dataSource = self;
    tableView.bounces = NO;
    tableView.rowHeight = kMenuItemsHeight;
    tableView.showsVerticalScrollIndicator = NO;
    tableView.backgroundColor = [UIColor clearColor];
    tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    [tableView registerClass:[MenuTableViewCell class] forCellReuseIdentifier:NSStringFromClass([MenuTableViewCell class])];
    
    self.contentTableView = tableView;
    self.height = tableView.height + kTriangleHeight * 2 - 0.5;
    self.alpha = 0;
    
    UIView *backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
    
    backView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.3];
    [backView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]];
    backView.alpha = 0;
    backView.tag = kMarkViewTag;
    _backView = backView;
    [[UIApplication sharedApplication].keyWindow addSubview:backView];
    
    CAShapeLayer *layer = [self getBorderLayer];
    self.layer.mask = layer;
    [self addSubview:tableView];
    [[UIApplication sharedApplication].keyWindow addSubview:self];
    
}

#pragma mark - 类方法 创建菜单
+ (MenuView *)createMenuWithFrame:(CGRect)frame target:(UIViewController *)target dataArray:(NSArray *)dataArray itemsClickBlock:(void (^)(NSString *, NSInteger))itemsClickBlock backViewTap:(void (^)())backViewTapBlock {
    
    CGFloat menuWidth = frame.size.width ? frame.size.width : 120;
    
    MenuView *menuView = [[MenuView alloc] initWithFrame:CGRectMake(0, 0, menuWidth, kMenuItemsHeight * dataArray.count)];
    menuView.selfMenu = menuView;
    menuView.itemsClickBlock = itemsClickBlock;
    menuView.backViewTapBlock = backViewTapBlock;
    menuView.menuDataArray = [NSMutableArray arrayWithArray:dataArray];
    menuView.maxValueForItemCount = 6;
    menuView.tag = kMenuTag;
    
    return menuView;
}

- (void)displayAtPoint:(CGPoint)point {
    
    
    point = [self.superview convertPoint:point toView:self.window];
    self.layer.affineTransform = CGAffineTransformIdentity;
    [self adjustPosition:point];
    
    // 调整箭头位置
    if (point.x <= kMargin + kRadius + kTriangleHeight * 0.7) {
        arrowPointX = kMargin + kRadius;
    } else if (point.x >= [UIScreen mainScreen].bounds.size.width - kMargin - kRadius - kTriangleHeight * 0.7) {
        arrowPointX = self.width - kMargin - kRadius;
    } else {
        arrowPointX = point.x - self.x;
    }
    
    // 调整 anchorPoint
    CGPoint aPoint = CGPointMake(0.5, 0.5);
    if (CGRectGetMaxY(self.frame) > [UIScreen mainScreen].bounds.size.height) {
        aPoint = CGPointMake(arrowPointX / self.width, 1);
    } else {
        aPoint = CGPointMake(arrowPointX / self.width, 0);
    }
    
    // 调整layer
    
    CAShapeLayer *layer = [self getBorderLayer];
    if (self.max_Y > [UIScreen mainScreen].bounds.size.height) {
        layer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
        layer.transform = CATransform3DRotate(layer.transform, M_PI, 0, 0, 1);
        self.y = point.y - self.height;
    }
    
    // 调整 frame
    CGRect frame = self.frame;
    self.layer.anchorPoint = aPoint;
    self.frame = frame;
    
    self.layer.mask = layer;
    self.layer.affineTransform = CGAffineTransformMakeScale(0.01, 0.01);
    [UIView animateWithDuration:0.25 animations:^{
        self.alpha = 1;
        _backView.alpha = 0.3;
        self.layer.affineTransform = CGAffineTransformMakeScale(1.0, 1.0);
    }];
}

// 调整展示的位置 - frame
- (void)adjustPosition:(CGPoint)point {
    self.x = point.x - self.width * 0.5;
    self.y = point.y + kMargin;
    if (self.x < kMargin) {
        self.x = kMargin;
    } else if (self.x > [UIScreen mainScreen].bounds.size.width - self.width - kMargin) {
        self.x = [UIScreen mainScreen].bounds.size.width - kMargin - self.width;
    }
    self.layer.affineTransform = CGAffineTransformMakeScale(1.0, 1.0);
}

#pragma mark - UITableViewDelegate / DataSource 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.menuDataArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    MenuTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MenuTableViewCell class]) forIndexPath:indexPath];
    MenuModel *model = self.menuDataArray[indexPath.row];
    cell.model = model;
    cell.backgroundColor = [UIColor clearColor];
    return cell;
    
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    MenuModel *model = self.menuDataArray[indexPath.row];
    if (self.itemsClickBlock) {
        self.itemsClickBlock(model.itemName, indexPath.row + 1);
    }
    
}


#pragma mark - 上下左右的圆角中心点
- (CAShapeLayer *)getBorderLayer {
    
    CGPoint upperLeftCornerCenter = CGPointMake(kRadius, kTriangleHeight + kRadius);
    CGPoint upperRightCornerCenter = CGPointMake(self.width - kRadius, kTriangleHeight + kRadius);
    CGPoint bottomLeftCornerCenter = CGPointMake(kRadius, self.height - kTriangleHeight - kRadius);
    CGPoint bottomRightCornerCenter = CGPointMake(self.width - kRadius, self.height - kTriangleHeight - kRadius);
    
    CAShapeLayer *borderLayer = [CAShapeLayer layer];
    borderLayer.frame = self.bounds;
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:CGPointMake(0, kTriangleHeight + kRadius)];
    [bezierPath addArcWithCenter:upperLeftCornerCenter radius:kRadius startAngle:M_PI endAngle:M_PI * 3 * 0.5 clockwise:YES];
    [bezierPath addLineToPoint:CGPointMake(arrowPointX - kTriangleHeight * 0.7, kTriangleHeight)];
    [bezierPath addLineToPoint:CGPointMake(arrowPointX, 0)];
    [bezierPath addLineToPoint:CGPointMake(arrowPointX + kTriangleHeight * 0.7, kTriangleHeight)];
    [bezierPath addLineToPoint:CGPointMake(self.width - kRadius, kTriangleHeight)];
    [bezierPath addArcWithCenter:upperRightCornerCenter radius:kRadius startAngle:M_PI *3 * 0.5 endAngle:0 clockwise:YES];
    [bezierPath addLineToPoint:CGPointMake(self.width, self.height - kTriangleHeight - kRadius)];
    [bezierPath addArcWithCenter:bottomRightCornerCenter radius:kRadius startAngle:0 endAngle:M_PI_2 clockwise:YES];
    [bezierPath addLineToPoint:CGPointMake(kRadius, self.height - kTriangleHeight)];
    [bezierPath addArcWithCenter:bottomLeftCornerCenter radius:kRadius startAngle:M_PI_2 endAngle:M_PI clockwise:YES];
    [bezierPath addLineToPoint:CGPointMake(0, kTriangleHeight + kRadius)];
    [bezierPath closePath];
    borderLayer.path = bezierPath.CGPath;
    return borderLayer;
}

- (void)updateFrameForMenu {
    
    MenuView *menuView = [[UIApplication sharedApplication].keyWindow viewWithTag:kMenuTag];
    menuView.maxValueForItemCount = menuView.menuDataArray.count;
    menuView.transform = CGAffineTransformMakeScale(1.0, 1.0);
    menuView.contentTableView.height = kMenuItemsHeight * menuView.menuDataArray.count;
    menuView.height = kMenuItemsHeight * menuView.maxValueForItemCount + kTriangleHeight * 2 - 0.5;
    menuView.layer.mask = [menuView getBorderLayer];
    menuView.transform = CGAffineTransformMakeScale(0.01, 0.01);
}

- (void)tap:(UITapGestureRecognizer *)sender {
    
    if (self.backViewTapBlock) {
        self.backViewTapBlock();
    }
    [self hiddenMenu];
}

- (void)hiddenMenu {
    self.contentTableView.contentOffset = CGPointZero;
    [UIView animateWithDuration:0.25 animations:^{
        self.layer.affineTransform = CGAffineTransformMakeScale(0.01, 0.01);
        self.alpha = 0;
        _backView.alpha = 0;
    }];
}

+ (void)hidden {
    MenuView *menuView = [[UIApplication sharedApplication].keyWindow viewWithTag:kMenuTag];
    [menuView hiddenMenu];
}

+ (void)showMenuAtPoint:(CGPoint)point {
    
    MenuView *menuView = [[UIApplication sharedApplication].keyWindow viewWithTag:kMenuTag];
    [menuView displayAtPoint:point];
}



+ (void)clearMenu {
    [MenuView hidden];
    MenuView *menuView = [[UIApplication sharedApplication].keyWindow viewWithTag:kMenuTag];
    UIView *coverView = [[UIApplication sharedApplication].keyWindow viewWithTag:kMarkViewTag];
    [menuView removeFromSuperview];
    [coverView removeFromSuperview];
}

+ (void)appendMenuItemsWith:(NSArray *)appendItemsArray {
    MenuView *menuView = [[UIApplication sharedApplication].keyWindow viewWithTag:kMenuTag];
    NSMutableArray *tempM = [NSMutableArray arrayWithArray:menuView.menuDataArray];
    [tempM addObjectsFromArray:appendItemsArray];
    menuView.menuDataArray = tempM;
    [menuView.contentTableView reloadData];
    [menuView updateFrameForMenu];
}

+ (void)updateMenuItemsWith:(NSArray *)newItemArray {
    MenuView *menuView = [[UIApplication sharedApplication].keyWindow viewWithTag:kMenuTag];
    [menuView.menuDataArray removeAllObjects];
    menuView.menuDataArray = [NSMutableArray arrayWithArray:newItemArray];
    [menuView.contentTableView reloadData];
    [menuView updateFrameForMenu];
}

@end


#pragma mark - MenuTableViewCell
@implementation MenuTableViewCell {
    UIView *_lineView;
}

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self == [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        [self setupUI];
    }
    return self;
}

- (void)setupUI {
    
    UIView *lineView = [[UIView alloc] init];
    lineView.backgroundColor = [UIColor lightGrayColor];
    _lineView = lineView;
    
    [self addSubview:lineView];
    self.backgroundColor = [UIColor clearColor];
    self.textLabel.font = [UIFont systemFontOfSize:14];
    self.textLabel.textColor = [UIColor whiteColor];
    self.selectionStyle = UITableViewCellAccessoryNone;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    _lineView.frame = CGRectMake(4, self.bounds.size.height - 1, self.bounds.size.width - 8, 0.5);
}

- (void)setModel:(MenuModel *)model {
    _model = model;
    self.imageView.image = [UIImage imageNamed:model.imageName];
    self.textLabel.text = model.itemName;
}

@end

#pragma mark - MenuModel 模型
@implementation MenuModel


- (instancetype)initWithDick:(NSDictionary *)dict {
    if (self == [super init]) {
        [self setValuesForKeysWithDictionary:dict];
    }
    return self;
}

+ (instancetype)MenuModelWithDict:(NSDictionary *)dict {
    return [[self alloc] initWithDick:dict];
}
@end
